<?php
/**
 * PsiFramework
 *
 * Php Simple Framework
 *
 * PHP version 5.3
 *
 * @category  PsiFramework.Plugins.Form.Classes.Util.Json
 * @package   PsiFramework.Plugins.Form.Classes.Util.Json
 * @author    Remi San <remi.san@gmail.com>
 * @copyright 2011 Remi San
 * @license   http://creativecommons.org/licenses/by/3.0/  Creative Commons CC BY 3.0
 * @version   SVN: <svn_id>
 * @link      http://www.psiframework.com/phpdoc/classes/db_\PsiFramework\Plugins\Form\Classes\Util\Json\JsonForm.html
 */

namespace PsiFramework\Plugins\Form\Classes\Util\Json;

import("Classes.Model.ModelInterface.IPrimitiveObject");
import("Plugins.Form.Classes.Util.Json.JsonField");
import("Classes.Util.Object.Json");

use \PsiFramework\Classes\Model\ModelInterface\IPrimitiveObject;
use \PsiFramework\Plugins\Form\Classes\Util\Json\JsonField;
use \PsiFramework\Plugins\Form\Classes\Util\Json\JsonFormElement;
use \PsiFramework\Plugins\Form\Classes\Util\Json\Elements\JsonFormInput;
use \PsiFramework\Plugins\Form\Classes\Util\Json\Elements\JsonFormOption;
use \PsiFramework\Plugins\Form\Classes\Util\Json\Elements\JsonFormTitle;
use \PsiFramework\Plugins\Form\Classes\Util\Json\Elements\JsonFormText;
use \PsiFramework\Classes\Util\Object\Json;
use \PsiFramework\Classes\Util\Database\Query\SqlType;

/**
 * The json Form class
 *
 * This is the json form model class
 *
 * @category PsiFramework.Plugins.Form.Classes.Util.Json
 * @package  PsiFramework.Plugins.Form.Classes.Util.Json
 * @author   Remi San <remi.san@gmail.com>
 * @license  http://creativecommons.org/licenses/by/3.0/  Creative Commons CC BY 3.0
 * @link     http://www.psiframework.com/phpdoc/classes/db_\PsiFramework\Plugins\Form\Classes\Util\Json\JsonForm.html
 */
class JsonForm implements IPrimitiveObject
{
    /**
     * @var array
     */
    protected /*JsonField[]*/ $_elements ;

    /**
     * Constructor
     *
     * @param array $elements The elements
     * 
     * @return JsonForm
     */
    public function __construct(/*JsonFormElement[]*/ $elements=array())
    {
        $this->_elements = $elements ;
    }

    /**
     * The function that builds the form from the json
     * 
     * @param Json   $json      The json object
     * @param string $fieldName The name of the field
     * 
     * @return void
     */
    public function buildFromJson(Json $json, /*string*/ $fieldName=null)
    {
        if (is_null($json->getObject())) {
            return ;
        }

        foreach ($json->getObject() as $field) {

            $formField = new JsonField();
            if (isNullOrEmptyString($fieldName)) {
                $formField->setName($field->name);
            } else {
                $formField->setName($fieldName);
            }
            
            if (isset($field->className)) {
                $formField->setClass($field->className);
            }
            
            if (isset($field->style)) {
            	$formField->setStyle($field->style);
            }
            
            if (isset($field->group)) {
            	$formField->setGroup($field->group);
            }

            $elements = array();

            foreach ($field->elements as $element) {
                $formElement = null ;
                $type = $element->type ;
                switch($type) {
                case 'text' :
                case 'hour' :
                case 'date' :
                case 'file' :
                case 'textarea' :
                case 'radio' :
                case 'checkbox' :
                case 'select' :
                    $formElement = new JsonFormInput();
                    $formElement->setInputType($type);
                    $formElement->setName($element->name);
                    if (isset($element->defaultValue)) {
                        $formElement->setValue($element->defaultValue);
                    }
                    if (isset($element->mandatory)) {
                        $formElement->setMandatory($element->mandatory);
                    }
                    if (isset($element->minLength)) {
                        $formElement->setMinLength($element->minLength);
                    }
                    if (isset($element->maxLength)) {
                        $formElement->setMaxLength($element->maxLength);
                    }
                    if (isset($element->string)) {
                        $formElement->setString($element->string);
                    }
                    if (isset($element->numeric)) {
                        $formElement->setNumeric($element->numeric);
                    }
                    if (isset($element->float)) {
                        $formElement->setFloat($element->float);
                    }
                    if (isset($element->displayAsImage)) {
                    	$formElement->setDisplayAsImage($element->displayAsImage);
                    }
                    if (isset($element->image)) {
                    	$formElement->setImage($element->image);
                    }
                    if (isset($element->imageWidth)) {
                    	$formElement->setImageWidth($element->imageWidth);
                    }
                    if (isset($element->imageHeight)) {
                    	$formElement->setImageHeight($element->imageHeight);
                    }

                    $options = array();
                    if (isset($element->options)) {
                        if (!is_null($element->options)) {
                            foreach ($element->options as $elementOption) {
                                $option = new JsonFormOption(
                                    $elementOption->value
                                );
                                if (isset($elementOption->selected)) {
                                    $option->setSelected(
                                        $elementOption->selected
                                    );
                                }
                                $options[] = $option ;
                            }
                        }
                    }
                    $formElement->setOptions($options);

                    break ;
                case 'title' :
                    $formElement = new JsonFormTitle();
                    break ;
                case 'p' :
                    $formElement = new JsonFormText();
                    break ;
                case 'clear-both' :
                    $formElement = new JsonFormElement();
                    break;
                }
                if (!is_null($formElement)) {
                    $formElement->setLabel($element->label);
                    if (isset($element->style)) {
                        $formElement->setStyle($element->style);
                    }
                    if (isset($element->className)) {
                        $formElement->setClassName($element->className);
                    }
                    if (isset($element->displayWithValues)) {
                        $formElement->setDisplayWithValues(
                            $element->displayWithValues
                        );
                    }
                    if (isset($element->group)) {
                    	$formElement->setGroup(
                			$element->group
                    	);
                    }
                    
                    $elements[] = $formElement ;
                }
            }

            $formField->setElements($elements);
            $this->addElement($formField);
        }
    }

    /**
     * The function that build the json object from the form (serialization)
     * 
     * @return Json
     */
    public function buildJson()
    {

        $fields = array();

        foreach ($this->_elements as $field) {

            $formField = new \stdClass();
            $formField->name = $field->getName();
            
            if (!isNullOrEmptyString($field->getClass())) {
                $formField->className = $field->getClass();
            }
            
            if (!isNullOrEmptyString($field->getStyle())) {
            	$formField->style = $field->getStyle();
            }
            
            if (!isNullOrEmptyString($field->getGroup())) {
            	$formField->group = $field->getGroup();
            }

            $elements = array();
            foreach ($field->getElements() as $element) {
                $elemClass = new \stdClass();
                $elemClass->label = $element->getLabel();
                $elemClass->style = $element->getStyle();
                $elemClass->className = $element->getClassName();
                $elemClass->displayWithValues = $element->isDisplayedWithValues();
                $elemClass->group = $element->getGroup();

                if ($element instanceof JsonFormInput) {
                    $elemClass->type = $element->getInputType();
                    $elemClass->name = $element->getName();
                    $elemClass->mandatory = $element->isMandatory();
                    
                    if ($element->getInputType() == 'file') {
                    	$elemClass->image = $element->isImage();
                    	if (!isNullOrEmptyString($element->getImageWidth())) {
                    	    $elemClass->imageWidth = $element->getImageWidth();
                    	}
                    	if (!isNullOrEmptyString($element->getImageHeight())) {
                    		$elemClass->imageHeight = $element->getImageHeight();
                    	}
                    }
                    
                    if ($element->getInputType() == 'text'
                        || $element->getInputType() == 'textarea'
                    ) {
                        $elemClass->minLength = $element->getMinLength();
                        $elemClass->maxLength = $element->getMaxLength();
                    }
                    if ($element->getInputType() == 'text') {
                        $elemClass->string = $element->isString();
                        $elemClass->numeric = $element->isNumeric();
                        $elemClass->float = $element->isFloat();
                        $elemClass->displayAsImage = $element->isDisplayedAsImage();
                    }

                    if (!is_null($element->getValue())) {
                        $elemClass->defaultValue = $element->getValue();
                    }
                    if (!is_null($element->getOptions())) {
                        $elemOptions = array();
                        foreach ($element->getOptions() as $option) {
                            $elemOption = new \stdClass();
                            $elemOption->value = $option->getValue();
                            $elemOption->selected = $option->isSelected();
                            $elemOptions[] = $elemOption ;
                        }
                        $elemClass->options = $elemOptions ;
                    }

                } else if ($element instanceof JsonFormTitle) {
                    $elemClass->type = 'title' ;
                } else if ($element instanceof JsonFormText) {
                    $elemClass->type = 'p' ;
                } else {
                    $elemClass->type = 'clear-both' ;
                }

                $elements[] = $elemClass ;
            }
            $formField->elements = $elements ;
            $fields[] = $formField ;
        }

        return new Json($fields);
    }

    /**
     * Getter for the elements
     *
     * @return JsonField[]
     */
    public function getElements()
    {
        return $this->_elements ;
    }

    /**
     * Function that returns the element at the specified index
     * 
     * @param int $index The index
     * 
     * @return JsonField
     */
    public function getElement($index)
    {
        return $this->_elements[$index] ;
    }

    /**
     * Setter for the elements
     *
     * @param string $elements The elements
     *
     * @return void
     */
    public function setElements(/*JsonFormElement[]*/ $elements)
    {
        $this->_elements = $elements ;
    }

    /**
     * Function that adds a field to the form
     *
     * @param JsonField $element The field to add
     *
     * @return void
     */
    public function addElement(JsonField $element)
    {
        if (is_null($this->_elements)) {
            $this->_elements = array();
        }
        $this->_elements[] = $element ;
    }

    /**
     * The function that serializes the JsonForm
     * 
     * @param bool $asText return the serialized object as text ?
     * 
     * @see IPrimitiveObject::serialize()
     * 
     * @return mixed
     */
    public function serialize(/*bool*/ $asText=true)
    {
        return $this->buildJson()->serialize($asText);
    }

    /**
     * The function that uneserializes the JsonForm
     *
     * @param string $text The text to unserialize
     *
     * @see IPrimitiveObject::unserialize()
     *
     * @return void
     */
    public function unserialize(/*string*/ $text)
    {
        $json = new Json();
        $json->unserialize($text);
        $this->buildFromJson($json);
    }

    /**
     * Shows the JsonForm as a string
     *
     * @see IPrimitiveObject::toString()
     *
     * @return string
     */
    public function toString()
    {

    }

    /**
     * The function that returns the sql type used to store
     * the json form object in database
     *
     * @see IPrimitiveObject::getSqlType()
     *
     * @return string
     */
    public static function getSqlType()
    {
        return SqlType::$text ;
    }

}
